using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Acme.BookStore.Domain.Entities;
using Acme.BookStore.EntityFrameworkCore;
using Acme.BookStore.Products;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;

namespace Acme.BookStore.EntityFrameworkCore.Products
{
    public class ShopWhereRepository : EfCoreRepository<BookStoreDbContext, ShopWhere>, IShopWhereRepository
    {
        public ShopWhereRepository(IDbContextProvider<BookStoreDbContext> dbContextProvider) 
            : base(dbContextProvider)
        {
        }

        public async Task<List<ShopWhere>> GetListAsync(
            int skipCount,
            int maxResultCount,
            string sorting,
            string filter = null)
        {
            var dbSet = await GetDbSetAsync();
            return await dbSet
                .WhereIf(
                    !filter.IsNullOrWhiteSpace(),
                    shopWhere => shopWhere.ProductName.Contains(filter)
                )
                .OrderBy(sorting)
                .Skip(skipCount)
                .Take(maxResultCount)
                .ToListAsync();
        }

        public async Task<List<ShopWhere>> SearchByNameAsync(
            int skipCount,
            int maxResultCount,
            string sorting,
            string nameKeyword)
        {
            var dbSet = await GetDbSetAsync();
            return await dbSet
                .WhereIf(
                    !nameKeyword.IsNullOrWhiteSpace(),
                    shopWhere => shopWhere.ProductName.Contains(nameKeyword)
                )
                .OrderBy(sorting)
                .Skip(skipCount)
                .Take(maxResultCount)
                .ToListAsync();
        }

        public async Task<List<ShopWhere>> GetListAsync(
            int skipCount,
            int maxResultCount,
            string sorting,
            string filter = null,
            string ownerCode = null,
            string productCode = null,
            string productName = null)
        {
            var dbSet = await GetDbSetAsync();
            return await dbSet
                .WhereIf(
                    !filter.IsNullOrWhiteSpace(),
                    shopWhere => 
                        shopWhere.ProductName.Contains(filter) ||
                        shopWhere.ProductCode.Contains(filter) ||
                        shopWhere.OwnerCode.Contains(filter)
                )
                .WhereIf(
                    !ownerCode.IsNullOrWhiteSpace(),
                    shopWhere => shopWhere.OwnerCode.Contains(ownerCode)
                )
                .WhereIf(
                    !productCode.IsNullOrWhiteSpace(),
                    shopWhere => shopWhere.ProductCode.Contains(productCode)
                )
                .WhereIf(
                    !productName.IsNullOrWhiteSpace(),
                    shopWhere => shopWhere.ProductName.Contains(productName)
                )
                .OrderBy(sorting)
                .Skip(skipCount)
                .Take(maxResultCount)
                .ToListAsync();
        }

        public async Task<long> GetCountAsync(string filter = null)
        {
            var dbSet = await GetDbSetAsync();
            return await dbSet
                .WhereIf(
                    !filter.IsNullOrWhiteSpace(),
                    shopWhere => shopWhere.ProductName.Contains(filter)
                )
                .CountAsync();
        }

        public async Task<long> GetCountByNameAsync(string nameKeyword)
        {
            var dbSet = await GetDbSetAsync();
            return await dbSet
                .WhereIf(
                    !nameKeyword.IsNullOrWhiteSpace(),
                    shopWhere => shopWhere.ProductName.Contains(nameKeyword)
                )
                .CountAsync();
        }

        public async Task<long> GetCountAsync(
            string filter = null,
            string ownerCode = null,
            string productCode = null,
            string productName = null)
        {
            var dbSet = await GetDbSetAsync();
            return await dbSet
                .WhereIf(
                    !filter.IsNullOrWhiteSpace(),
                    shopWhere => 
                        shopWhere.ProductName.Contains(filter) ||
                        shopWhere.ProductCode.Contains(filter) ||
                        shopWhere.OwnerCode.Contains(filter)
                )
                .WhereIf(
                    !ownerCode.IsNullOrWhiteSpace(),
                    shopWhere => shopWhere.OwnerCode.Contains(ownerCode)
                )
                .WhereIf(
                    !productCode.IsNullOrWhiteSpace(),
                    shopWhere => shopWhere.ProductCode.Contains(productCode)
                )
                .WhereIf(
                    !productName.IsNullOrWhiteSpace(),
                    shopWhere => shopWhere.ProductName.Contains(productName)
                )
                .CountAsync();
        }
    }
} 